/* cl.ext.select2tree 0.1*/
(
    function (factory) {
        if (typeof define === 'function' && define.amd) {
            define(['jquery',"jsTree"], factory);
        } else if (typeof module === 'object' && module.exports) {
            module.exports = function( root, jQuery ) {
                //var reqSelect2 = require('Select2');
                var reqJsTree = require('jsTree');
                if ( jQuery === undefined ) {
                    if ( typeof window !== 'undefined' ) {
                        jQuery = require('jquery');
                    }
                    else {
                        jQuery = require('jquery')(root);
                    }
                }
                factory(jQuery);
            };
        } else {
            factory(jQuery);
        }
    }(
    function ($){
        var defaultTree={"core" : {"themes": {"responsive": false},"cache": false,'data' :[]},"types" : {"default" : {"icon" : false}},'plugins' : ['types','search']};
        var defaults={width:"w-400",url:"",treeOverflowHeight:"300",data:[],treeinfo:defaultTree,placeholder:"-请选择-",initValue:"",initCallback:null,changeCallback:null};
        var $modalCommon={
            getDefaults :function () {
                defaults.infoLoad=$.ExtAjax.initGetDefault({});
                return defaults
            },
            getOptions : function (elementData,options) {
                options=$.ExtCommon.isCheckEmpty(options)?{}:options;
                var optionBase=$.ExtCommon.initMergeJson(elementData, options);
                optionBase =$.ExtCommon.initMergeJson(this.getDefaults(),optionBase);
                return optionBase
            }
        };
        var modalOperateElement=function(element,options){
            var self=this;
            self.elementModal = element;
            self.optionModal=options;
        };
        modalOperateElement.prototype = {
            init:function(){
                var self=this;
                self.optionModal.treeinfo.core.data=self.optionModal.data.length>0?self.optionModal.data:[];
                self.elementModal.tree.jstree(self.optionModal.treeinfo).off("select_node.jstree").on('select_node.jstree', function (e, data) {
                    if(data.node.children.length==0){
                        self.setTreeSelectName(data.node.id,data.node.text);
                        self.hide();
                    }
                });
                if(!$.ExtCommon.isCheckEmpty(self.optionModal.initValue)){
                    self.setTreeSelectName(self.optionModal.initValue,null);
                }
                self.bindEvent();
            },
            bindEvent:function () {
                var self=this;
                self.elementModal.btnSelect2Tree.on("click",function(){
                    var _this=$(this);
                    if(_this.hasClass("select2-container--open")){
                        self.elementModal.txtKeyWord.val("");
                        self.hide();
                    }else{
                        self.setTreeSelectNode(_this.data("treenodeid"));
                        self.setScrollTop(".jstree-clicked");
                        self.show()
                    }
                });
                self.elementModal.dialogSelect2Tree.off("click.dialogmodal.close").on("click.dialogmodal.close", function(e){
                    if(e.currentTarget== e.target){self.hide();}
                });
                self.elementModal.bgSelect2Tree.off("click").on("click", function(){
                    self.hide();
                });
                self.elementModal.btnSearch.off("click").on("click", function(){
                    self.searchTreeKey(self.elementModal.txtKeyWord.val());
                });
                self.elementModal.txtKeyWord.off("keyup").on("keyup", function (event) {
                    if (event.keyCode == 13) {
                        self.searchTreeKey($.trim($(this).val()));
                    }
                });
            },
            setTreeSelectNode:function(id){
                var objTree=this.elementModal.tree.jstree();
                objTree["close_all"]();
                objTree["deselect_all"]();
                objTree["clear_search"]();
                objTree["select_node"](id,false,false);
            },
            isCheckSelect2Tree:function(id){
                var objTree=this.elementModal.tree.jstree();
                var deferred = new $.Deferred;
                var check=function(id){
                    var info=objTree["get_node"](id);
                    if(info){
                        deferred.resolve();
                    }else{
                        setTimeout(function(){check(id);},100)
                    }
                };
                check(id);
                return deferred.promise();
            },
            getSelectParentNames:function(id,cb){
                var self=this;
                var strNames="";
                id=id.toString();
                if($.ExtCommon.isCheckEmpty(id)){
                    if(cb)cb("");
                }else{
                    $.when(this.isCheckSelect2Tree(id)
                        .done(function(){
                            var objTree=self.elementModal.tree.jstree();
                            var info=objTree["get_node"](id);
                            if(info.parents && info.parents.length>0){
                                var names=$.map(info.parents,function(info){
                                    if(info.length>0&&info!="#"&&info!="0"){
                                        return objTree["get_node"](info).text;
                                    }
                                });
                                strNames=names.reverse().join("-");
                            }
                            strNames=strNames.length==0?info.text:strNames+"-"+info.text;
                            if(cb)cb(strNames);
                        })
                        .fail(function(){
                            if(cb)cb("");
                        })
                    );
                }
            },
            setTreeSelectName:function(id,text,isChange){
                var self=this;
                isChange=$.ExtCommon.isCheckUndefined(isChange)?true:isChange;
                if(!$.ExtCommon.isCheckEmpty(id) && $.ExtCommon.isCheckEmpty(text)){
                    $.each(self.optionModal.data,function(i,info){
                        if(info.id==self.optionModal.initValue) {
                            text=info.text;
                            return false;
                        }
                    });
                }

                var sid=self.elementModal.btnSelect2Tree.data("treenodeid");
                if(sid!=id){
                    this.getSelectParentNames(id,function(names){
                        var texts=$.ExtCommon.isCheckEmpty(id)?"":$.ExtCommon.isCheckEmpty(names)?text:names;
                        self.elementModal.btnSelect2Tree.data("treenodeid",id);
                        if($.ExtCommon.isCheckEmpty(texts)){
                            self.elementModal.btnSelect2Tree.find(".select2-selection__rendered").html('<span class="select2-selection__placeholder">'+self.optionModal.placeholder+'</span>');
                        }else{
                            self.elementModal.btnSelect2Tree.find(".select2-selection__rendered").text(texts);
                        }
                        self.elementModal.element.val(id.toString());
                        if(isChange && self.optionModal.changeCallback){self.optionModal.changeCallback(self.elementModal.element,id,text)}
                    });
                }
            },
            show:function(){
                this.elementModal.dialogSelect2Tree.find(".select2tree-keyword").val("");
                this.elementModal.btnSelect2Tree.addClass("select2-container--open");
                this.elementModal.dialogSelect2Tree.addClass("select2-container--open");
                this.elementModal.bgSelect2Tree.show();
            },
            hide:function(){
                this.elementModal.btnSelect2Tree.removeClass("select2-container--open");
                this.elementModal.dialogSelect2Tree.removeClass("select2-container--open");
                this.elementModal.bgSelect2Tree.hide();
            },
            setScrollTop:function(para){
                var objdropdown=this.elementModal.dialogSelect2Tree.find(".select2-tree");
                var objPara=this.elementModal.dialogSelect2Tree.find(para);
                if(objPara.length>0){
                    var positionTop=objPara.eq(0).position().top;
                    var scrollTop=objdropdown.scrollTop();
                    var distance=50;
                    if(scrollTop>0){
                        objdropdown.scrollTop(scrollTop+(positionTop-distance));
                    }else{
                        objdropdown.scrollTop(positionTop-distance);
                    }
                }else{
                    objdropdown.scrollTop(0);
                }
            },
            searchTreeKey:function(value){
                var searchKey= $.trim(value);
                if(searchKey.length>0){
                    this.elementModal.tree.jstree(true).search(searchKey);
                    this.setScrollTop(".jstree-search");
                }
            },
            remove:function(){
                this.elementModal.btnSelect2Tree.off("click");
                this.elementModal.dialogSelect2Tree.off("click.dialogmodal.close");
                this.elementModal.bgSelect2Tree.off("click");
                this.elementModal.btnSearch.off("click");
                this.elementModal.txtKeyWord.off("keyup");
                this.elementModal.parent.append(this.elementModal.element);
                this.elementModal.tree=null;
                this.elementModal.txtKeyWord=null;
                this.elementModal.btnSearch=null;
                this.elementModal.bgSelect2Tree=null;
                this.elementModal.btnSelect2Tree=null;
                this.elementModal.dialogSelect2Tree=null;
            }
        };
        var Select2TreeExtModal = function(element, options) {
            var self=this;
            self.element = $(element);
            self.optionBase=$modalCommon.getOptions(self.element.data(),options);
            var $templateHtml = $('<div class="select2-treedialog" style="position: relative;">'+
                '<span class="select2tree-bg"></span>'+
                '<span class="select2 select2-container select2-container--bootstrap select2-container--below '+self.optionBase.width+' select2tree-btn">'+
                    '<span class="selection">'+
                        '<span class="select2-selection select2-selection--single">'+
                            '<span class="select2-selection__rendered" ><span class="select2-selection__placeholder">'+self.optionBase.placeholder+'</span></span>'+
                            '<span class="select2-selection__arrow"><b role="presentation"></b></span>'+
                        '</span>'+
                    '</span>'+
                    '<span class="dropdown-wrapper"></span>'+
                '</span>'+
                '<span class="select2-container select2-container--bootstrap select2tree-dialog" style="">'+
                    '<span class="select2-dropdown select2-dropdown--below '+self.optionBase.width+'">'+
                        '<span class="select2-search select2-search--dropdown">'+
                            '<input class="select2-search__field select2tree-keyword" type="text">'+
                            '<i class="fa fa-search select2tree-search"></i>'+
                        '</span>'+
                        '<span class="select2-results">'+
                            '<div class="select2-tree" style="height: '+self.optionBase.treeOverflowHeight+'px">'+
                                '<div class="select2tree-list"></div>'+
                            '</div>'+
                        '</span>'+
                    '</span>'+
                '</span>'+
                '</div>');
            self.element.parent().append($templateHtml);
            self.element.prependTo($templateHtml);
            self.container=$templateHtml;
            self.elementContainer={
                element:this.element,
                tree:this.container.find(".select2tree-list"),
                txtKeyWord:this.container.find(".select2tree-keyword"),
                btnSearch:this.container.find(".select2tree-search"),
                bgSelect2Tree:this.container.find(".select2tree-bg"),
                btnSelect2Tree:this.container.find(".select2tree-btn"),
                dialogSelect2Tree:this.container.find(".select2tree-dialog"),
                parent:this.container.parent()
            };
            if(self.optionBase.url){
                $.ExtAjax.initGet({url:self.optionBase.url,data:{},
                    successCallback:function(res){
                        var list=res.success? res.data:[];
                        if(!res.success){ $.ExtNotify.error(res.msg);}
                        self.optionBase.dataOriginalAjax=list;
                        self.optionBase.data=$.ExtCommon.convertListByPara(list,{id:"id",text:"name",parent:{key:"parentId",value:"0",defaultValue:"#"}});
                        self._init();
                    }
                });
            }else if(self.optionBase.data){
                self._init();
            }
        };
        Select2TreeExtModal.prototype = {
            _init:function(){
                this.elementOperate=new modalOperateElement(this.elementContainer,this.optionBase);
                this.elementOperate.init();
                if(this.optionBase.initCallback){this.optionBase.initCallback(this.element)}
            },
            setValue:function (value,isChange) {
                this.elementOperate.setTreeSelectName(value,null,isChange);
            },
            hide:function () {
                this.elementOperate.hide();
            },
            "destroy":function(){
                if (!this.element) {
                    return;
                }
                this.elementOperate.remove();
                this.element.removeData("ExtSelect2Tree");
                this.container.empty().remove();
            }
        };
        $.fn.ExtSelect2Tree = function(options) {
            var dataFun;
            this.each(function() {
                var el = $(this);
                var tempData=el.data('ExtSelect2Tree');
                if (tempData){
                    if (typeof  options === "string") {
                        if (tempData[options]) {
                            dataFun =tempData[options]()
                        } else {
                            dataFun = tempData
                        }
                    } else {
                        dataFun = tempData
                    }
                }else {
                    dataFun = new Select2TreeExtModal(el, options);
                    el.data('ExtSelect2Tree', dataFun);
                }
            });
            return dataFun;
        };
        return Select2TreeExtModal;
    })
);
